package com.glsc.ngateway.amdoc.log;

import com.glsc.ngateway.amdoc.services.InterfaceService;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.TInterfaceAccessHistoryTable;
import com.glsc.ngateway.common.base.weblog.MDCUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.sql.Timestamp;
import java.time.Duration;
import java.time.LocalDateTime;


@Aspect
@Component
public class WebLogAspect {

    private final Logger logger = LoggerFactory.getLogger(WebLogAspect.class);

    @Autowired
    private InterfaceService interfaceService;


    @Pointcut("execution(public * com.glsc.ngateway.amdoc.controller..*.*(..))")
    public void webLog() {
    }

    @Around("webLog()")
    public Object aroundAdvice(ProceedingJoinPoint point) throws Throwable {
        MethodSignature methodSignature = (MethodSignature) point.getSignature();
        String[] paramNames = methodSignature.getParameterNames();
        Object[] values = point.getArgs();
        StringBuffer params = new StringBuffer();
        for (int i = 0; i < paramNames.length; i++) {
            if (values[i] != null && paramNames[i] != null) {
                params.append(paramNames[i] + ":" + (i < values.length ? values[i].toString() : "")).append(i == paramNames.length - 1 ? "" : ",");
            }
        }
        String interfaceName = methodSignature.getName();


        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        HttpServletResponse response = attributes.getResponse();

        MDC.put(MDCUtil.userKey, "user");
        MDC.put(MDCUtil.ipKey, request.getRemoteAddr());

        String url = request.getServletPath();
        String method = request.getMethod();
        Object[] args = point.getArgs();


        logger.info("Request------------------\r\nurl:{}\r\nip:{}\r\nmethod:{}\r\nargs:{}", url, request.getRemoteAddr(), method, args);
        LocalDateTime startdt = LocalDateTime.now();
        Object result = null;
        try {
            result = point.proceed(args);
            return result;
        } finally {
            LocalDateTime enddt = LocalDateTime.now();
            Duration duration = java.time.Duration.between(startdt, enddt);
            logger.info("Response------------------\r\nurl:{}\r\ncost:{}ms\r\nresult:{}", url, duration.toMillis(), result);
            interfaceService.insertInterfaceHistory(TInterfaceAccessHistoryTable.builder()
                    .params(params.toString())
                    .interfaceName("amdoc-" + interfaceName)
//                    .accessTime(new Timestamp(System.currentTimeMillis()))
                    .ip(request.getRemoteAddr())
                    .url(url)
                    .account(null)
                    .costTime(duration.toMillis())
                    .build());
            MDC.clear();
        }
    }


}
